from flask import Flask, jsonify, request, redirect, make_response, send_from_directory
from flasgger import Swagger
import os
import io
import ccm_workload_checker

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = 'upload/'

swagger = Swagger(app)

WORKLOAD_FOLDER = 'workload/'


def get_file_list(file_path):
    dir_list = os.listdir(file_path)
    if not dir_list:
        return []
    else:
        # 注意，这里使用lambda表达式，将文件按照最后修改时间顺序升序排列
        # os.path.getmtime() 函数是获取文件最后修改时间
        # os.path.getctime() 函数是获取文件最后创建时间
        dir_list = sorted(dir_list, key=lambda x: os.path.getmtime(os.path.join(file_path, x)))
        # print(dir_list)
        return dir_list


def glue(buffer, lines):
    for line in lines:
        buffer.write(line)


@app.route('/check', methods=['POST'])
def check():
    """请上传被检查的excel文件
    ---
    consumes:
      - multipart/form-data
    produces:
      - text/plain
    parameters:
      - name: file
        in: formData
        type: file
        required: true
        description: 被检查文件
      - name: force_save
        in: formData
        type: boolean
        required: false
        default: False
        description: 是否强制保存文件至历史，默认：否，仅当文件合规时自动保存至历史
    responses:
      200:
        description: Processed successfully!
      500:
        description: Internal server error!
    """

    f = request.files['file']
    new_workload = os.path.join(app.config['UPLOAD_FOLDER'], f.filename)
    f.save(new_workload)

    new_workload_ok = True
    summary = io.StringIO()
    summary.write('开始检查“{0}”...\n'.format(f.filename))

    checker = ccm_workload_checker.WorkloadChecker()
    checker.ReadExcel(new_workload)
    r = checker.CheckWorkloadLength()
    r.extend(checker.CheckIllegalWords())
    r.extend(checker.CheckDuplicate())
    if r:
        new_workload_ok = False
        glue(summary, r)

    workloads = get_file_list(WORKLOAD_FOLDER)
    if workloads:
        for workload in workloads:
            summary.write('正在对比“{0}”...\n'.format(workload))
            another_checker = ccm_workload_checker.WorkloadChecker()
            another_checker.ReadExcel(os.path.join(WORKLOAD_FOLDER, workload))
            r = checker.CheckDuplicateWithOther(another_checker)
            if r:
                new_workload_ok = False
                glue(summary, r)

    summary.write('“{0}”检查完成，文件{1}合规。\n'.format(f.filename, '' if new_workload_ok else '不'))

    force_save = request.form.get('force_save')
    if new_workload_ok or force_save == 'true':
        dest_workload = os.path.join(WORKLOAD_FOLDER, f.filename)
        try:
            os.rename(new_workload, dest_workload)
        except FileExistsError:
            os.remove(dest_workload)
            os.rename(new_workload, dest_workload)
        summary.write('“{0}”已保存至历史文件。\n'.format(f.filename))

    response = make_response(summary.getvalue(), 200)
    response.mimetype = "text/plain"
    return response


@app.route('/history')
def history():
    """历史文件列表
    ---
    produces:
      - application/json
    responses:
      200:
        description: Processed successfully!
      500:
        description: Internal server error!
    """
    workloads = get_file_list(WORKLOAD_FOLDER)
    return jsonify(workloads)


@app.route('/history/download/<filename>')
def download(filename):
    """下载历史文件
    ---
    produces:
      - application/octet-stream
    parameters:
      - name: filename
        in: path
        type: string
        required: true
        description: 下载文件名
    responses:
      200:
        description: Processed successfully!
      404:
        description: File not Found!
      500:
        description: Internal server error!
    """
    file = os.path.join(WORKLOAD_FOLDER, filename)
    if not os.path.exists(file):
        response = make_response('未找到文件“{0}”'.format(filename), 404)
        return response
    else:
        response = make_response(send_from_directory(WORKLOAD_FOLDER, filename, as_attachment=True))
        response.headers["Content-Disposition"] = "attachment; filename={}".format(filename.encode().decode('latin-1'))
        return response


@app.route('/')
def welcome():
    return redirect('/apidocs')


app.run(host='0.0.0.0', debug=True)
